/*****************************************************************************************
   
   Copyright (c) Microsoft Corporation. All rights reserved.

   Use of this code sample is subject to the terms of the Microsoft
   Permissive License, a copy of which should always be distributed with
   this file.  You can also access a copy of this license agreement at:
   http://www.microsoft.com/resources/sharedsource/licensingbasics/permissivelicense.mspx

 ****************************************************************************************/

using System;

namespace GrooveWebServicesV12Helpers.Files
{
	/// <summary>
	/// Represents a Groove Files tool.
	/// </summary>
	public class FilesTool : 
		GrooveWebServicesV12Helpers.Tool,
		GrooveWebServicesV12Helpers.Shared.IGrooveWebServicesEventCallback
	{
		internal static System.Collections.SortedList s_FilesToolEventManagerSortedList = new System.Collections.SortedList();

		private int m_FilesToolEventManagerCount = 0;
		
		private string m_RootFolderURI;
		private string m_FilesSubscriptionID;

		private GrooveWebServicesV12Helpers.Files.Folder m_RootFolder;

		private GrooveFilesWebService.GrooveFilesBase64 m_GrooveFiles;

		internal enum FilesType
		{
			File = 0x1,
			Folder = 0x2,
			All = File | Folder
		}

		public FilesTool(GrooveWebServicesV12Helpers.Space i_Space, GrooveToolsWebService.Tool i_Tool) :
			this(i_Space, i_Tool, false)
		{
			//  Make sure we are dealing with a 2.5 or later Files tool
			if (this.Type != GrooveWebServicesV12Helpers.Shared.GROOVE_FILES_TOOL_SUPPORTED_TYPE)
				throw new System.ArgumentException("Tool is not a Groove 2.5 or later Files tool!");
		}

        protected FilesTool(GrooveWebServicesV12Helpers.Space i_Space, GrooveToolsWebService.Tool i_Tool, bool i_Derived)
            : base(i_Space, i_Tool)
        {
            m_RootFolderURI = m_Tool.Data + "/$ComponentGroup";
        }

		#region Files Properties And Methods

		public static GrooveFilesWebService.GrooveFilesBase64 CreateInitializedFilesWebService(string i_IdentityURL, string i_TargetURI, GrooveWebServicesV12Helpers.Context i_Context)
		{
			//  Create the service
			GrooveFilesWebService.GrooveFilesBase64 FilesWebService = new GrooveFilesWebService.GrooveFilesBase64();

			//  Create the Groove SOAP header
			FilesWebService.GrooveRequestHeaderValue = new GrooveFilesWebService.GrooveRequestHeader();

			//  Set appropriate header values
			FilesWebService.GrooveRequestHeaderValue.GrooveRequestKey = i_Context.RequestKey;
			FilesWebService.GrooveRequestHeaderValue.GrooveIdentityURL = i_IdentityURL;

			//  Set the URL
			FilesWebService.Url = i_Context.Host + i_TargetURI;

			//  Set Timeout
			FilesWebService.Timeout = i_Context.Timeout;

			return FilesWebService;
		}

		/// <summary>
		/// Get the root folder.
		/// </summary>
		public GrooveWebServicesV12Helpers.Files.Folder RootFolder
		{
			get
			{
				if (m_RootFolder == null)
				{
					GrooveWebServicesV12Helpers.Files.Folder [] Folders = null;
					GrooveWebServicesV12Helpers.Files.File[] Files = null;
	
					int_GetContent
						(
						null,
						GrooveWebServicesV12Helpers.Files.FilesTool.FilesType.Folder,
						out Folders,
						out Files,
						false	// recursive
						);

					foreach (GrooveWebServicesV12Helpers.Files.Folder Folder in Folders)
					{
						if (Folder.ID == "$ComponentGroup")
						{
							m_RootFolder = Folder;
							break;
						}
					}
				}

				return m_RootFolder;
			}
		}

		/// <summary>
		/// Gets the URI of the root folder.
		/// </summary>
		public string RootFolderURI
		{
			get
			{
				return m_RootFolderURI;
			}
		}

		/// <summary>
		/// Get all content of the files tool.
		/// </summary>
		/// <param name="o_Folders">Out: array of Folders</param>
		/// <param name="o_Files">Out: array of Files</param>
		/// <param name="i_Recursive">True to search subfolders recursively</param>
		public void GetAllContent(out GrooveWebServicesV12Helpers.Files.Folder [] o_Folders, out GrooveWebServicesV12Helpers.Files.File[] o_Files, bool i_Recursive)
		{
			int_GetContent
				(
				null,
				GrooveWebServicesV12Helpers.Files.FilesTool.FilesType.All, 
				out o_Folders,
				out o_Files, 
				i_Recursive
				);
		}

		internal void int_GetContent(GrooveWebServicesV12Helpers.Files.Folder i_Folder, GrooveWebServicesV12Helpers.Files.FilesTool.FilesType i_FilesType, out GrooveWebServicesV12Helpers.Files.Folder [] o_Folders, out GrooveWebServicesV12Helpers.Files.File[] o_Files, bool i_Recursive)
		{
			//  Get appropriate target uri
			string TargetURI;
			if (i_Folder != null)
				TargetURI = i_Folder.URI;
			else
				TargetURI = this.Data;

			o_Folders = null;
			o_Files = null;

			GrooveFilesWebService.FileDescriptor[] FileDescriptors = int_GetFileDescriptors
				(
				TargetURI,
				i_Recursive
				);

			//  Create array  of files, if necessary
			if ((i_FilesType & GrooveWebServicesV12Helpers.Files.FilesTool.FilesType.File) != 0)
			{
				System.Collections.ArrayList FileArrayList = new System.Collections.ArrayList();
				foreach (GrooveFilesWebService.FileDescriptor FileDescriptor in FileDescriptors)
				{
					if (FileDescriptor.Type == "File")
					{
						GrooveWebServicesV12Helpers.Files.File File = new GrooveWebServicesV12Helpers.Files.File
							(
							this,
							i_Folder,
							FileDescriptor
							);

						FileArrayList.Add(File);
					}
				}

				//  Convert array list to array
				o_Files = (GrooveWebServicesV12Helpers.Files.File[])FileArrayList.ToArray(typeof(GrooveWebServicesV12Helpers.Files.File));
			}

			if ((i_FilesType & GrooveWebServicesV12Helpers.Files.FilesTool.FilesType.Folder) != 0)
			{
				System.Collections.ArrayList FolderArrayList = new System.Collections.ArrayList();
				foreach (GrooveFilesWebService.FileDescriptor FileDescriptor in FileDescriptors)
				{
					if (FileDescriptor.Type == "Folder")
					{
						GrooveWebServicesV12Helpers.Files.Folder Folder = new GrooveWebServicesV12Helpers.Files.Folder 
							(
							this,
							i_Folder,
							FileDescriptor
							);

						FolderArrayList.Add(Folder);
						}
				}

				//  Convert array list to array
				o_Folders = (GrooveWebServicesV12Helpers.Files.Folder [])FolderArrayList.ToArray(typeof(GrooveWebServicesV12Helpers.Files.Folder ));
			}
		}

		internal GrooveFilesWebService.FileDescriptor[] int_GetFileDescriptors(string i_TargetURI, bool i_Recursive)
		{
			//  Get initialized reference to web service
			GrooveFilesWebService.GrooveFilesBase64 FilesWebService = this.GetInitializedFilesWebService(i_TargetURI);

			System.DateTime BeginDateTime = System.DateTime.Now;

			//  Ask service to provide the list of folder entries for this tool
			GrooveFilesWebService.FileDescriptor[] FileDescriptors = FilesWebService.Read
				(
				i_Recursive,
				true		// recursive specified
				);

			if (GrooveWebServicesV12Helpers.Context.TraceEnabled)
			{
				System.TimeSpan TimeSpan = System.DateTime.Now.Subtract(BeginDateTime);
				System.Diagnostics.Debug.WriteLine("FilesWebService::Read, " + TimeSpan.TotalMilliseconds + " ms");
			}

			return FileDescriptors;
		}

		/// <summary>
		/// Find folders matching a keyword in their name
		/// </summary>
		/// <param name="i_Keyword">Partial name (case insensitive)</param>
		/// <param name="i_Recursive">True to search subfolders recursively</param>
		/// <returns>Array of Folders</returns>
		public GrooveWebServicesV12Helpers.Files.Folder [] FindMatchingFolders(string i_Keyword, bool i_Recursive)
		{
			return int_FindMatchingFolders
				(
				null,
				i_Keyword,
				i_Recursive
				);
		}

		internal GrooveWebServicesV12Helpers.Files.Folder [] int_FindMatchingFolders(GrooveWebServicesV12Helpers.Files.Folder i_Folder, string i_Keyword, bool i_Recursive)
		{
			//  Check for valid keyword
			if (i_Keyword.Length == 0)
				throw new System.ArgumentException("No keyword specified!");

			string NormalizedKeyword = i_Keyword.ToLower();

			//  Get appropriate target uri
			string TargetURI;
			if (i_Folder != null)
				TargetURI = i_Folder.URI;
			else
				TargetURI = this.Data;

			//  Get list of folder entries for this tool
			GrooveWebServicesV12Helpers.Files.Folder [] Folders = null;
			GrooveWebServicesV12Helpers.Files.File[] Files = null;

			int_GetContent
				(
				i_Folder,
				GrooveWebServicesV12Helpers.Files.FilesTool.FilesType.Folder,
				out Folders,
				out Files,
				i_Recursive
				);

			System.Collections.ArrayList FolderArrayList = new System.Collections.ArrayList();

			//  Only do work if folder entries exist
			if (Folders.Length > 0)
			{
				//  Iterate through folders
				foreach (GrooveWebServicesV12Helpers.Files.Folder Folder in Folders)
				{
					string NormalizedDisplayName = Folder.DisplayName.ToLower();

					bool FoundMatch = 
						(NormalizedDisplayName.IndexOf(NormalizedKeyword) >= 0);

					if (FoundMatch)
						FolderArrayList.Add(Folder);
				}
			}

			//  Return array from array list
			return (GrooveWebServicesV12Helpers.Files.Folder [])FolderArrayList.ToArray(typeof(GrooveWebServicesV12Helpers.Files.Folder ));
		}


		/// <summary>
		/// Find files matching a keyword in their name
		/// </summary>
		/// <param name="i_Keyword">Partial name (case insensitive)</param>
		/// <param name="i_Recursive">True to search subfolders recursively</param>
		/// <returns>Array of Files</returns>
		public GrooveWebServicesV12Helpers.Files.File[] FindMatchingFiles(string i_Keyword, bool i_Recursive)
		{
			return int_FindMatchingFiles
				(
				null,
				i_Keyword,
				i_Recursive
				);
		}

		internal GrooveWebServicesV12Helpers.Files.File[] int_FindMatchingFiles(GrooveWebServicesV12Helpers.Files.Folder i_Folder, string i_Keyword, bool i_Recursive)
		{
			//  Check for valid keyword
			if (i_Keyword.Length == 0)
				throw new System.ArgumentException("No keyword specified!");

			string NormalizedKeyword = i_Keyword.ToLower();

			GrooveWebServicesV12Helpers.Files.Folder [] Folders = null;
			GrooveWebServicesV12Helpers.Files.File[] Files = null;

			//  Get list of file entries for this tool
			this.int_GetContent
				(
				i_Folder,
				GrooveWebServicesV12Helpers.Files.FilesTool.FilesType.File,
				out Folders,
				out Files,
				i_Recursive
				);

			System.Collections.ArrayList FileArrayList = new System.Collections.ArrayList();

			//  Only do work if file entries exist
			if (Files.Length > 0)
			{
				//  Iterate through files
				foreach (GrooveWebServicesV12Helpers.Files.File File in Files)
				{
					string NormalizedName = File.Name.ToLower();

					bool FoundMatch = 
						(NormalizedName.IndexOf(NormalizedKeyword) >= 0);

					if (FoundMatch)
						FileArrayList.Add(File);
				}
			}

			//  Return array from array list
			return (GrooveWebServicesV12Helpers.Files.File[])FileArrayList.ToArray(typeof(GrooveWebServicesV12Helpers.Files.File));
		}

		protected GrooveFilesWebService.GrooveFilesBase64 GetInitializedFilesWebService(string i_TargetURI)
		{
            if ((m_GrooveFiles == null) || Context.ReinitNeeded(m_GrooveFiles.GrooveRequestHeaderValue.GrooveRequestKey))
			{
				m_GrooveFiles = GrooveWebServicesV12Helpers.Files.FilesTool.CreateInitializedFilesWebService
					(
					m_IdentityURL,
					i_TargetURI,
					Context
					);
			}
			else
			{
				//  Explicitly overwrite target URL and Timeout
				m_GrooveFiles.Url = Context.Host + i_TargetURI;
                m_GrooveFiles.Timeout = Context.Timeout;
			}

			return m_GrooveFiles;
		}

		#endregion

		#region Files Event Handling

		private void IncrementFilesToolSubscriptionCount()
		{
			lock (s_FilesToolEventManagerSortedList)
			{
				if (m_FilesToolEventManagerCount == 0)
				{
					m_FilesSubscriptionID = GrooveWebServicesV12Helpers.EventManager.AddEventListener
						(
						Context,
						this.IdentityURL,
						GrooveWebServicesV12Helpers.Shared.GROOVE_WEB_SERVICES_FILES_EVENT_CLASS,
						this.Data,
						GrooveWebServicesV12Helpers.EventManager.s_EventURI,
						this
						);
				}

				++m_FilesToolEventManagerCount;
			}
		}

		private void DecrementFilesToolSubscriptionCount()
		{
			lock (s_FilesToolEventManagerSortedList)
			{
				--m_FilesToolEventManagerCount;

				if (m_FilesToolEventManagerCount == 0)
				{
					GrooveWebServicesV12Helpers.EventManager.RemoveEventListener
						(
						m_FilesSubscriptionID,
						this
						);

					m_FilesSubscriptionID = null;
				}
			}
		}

		internal void RaiseFileDescriptorAddedEvent(GrooveFilesWebService.FileDescriptor i_FileDescriptor)
		{
			if (i_FileDescriptor.Type == "Folder")
			{
				//  If one or more subscribers, broadcast event
				if (InternalOnFolderAddedEvent != null)
				{
					GrooveWebServicesV12Helpers.Files.Folder Folder = new GrooveWebServicesV12Helpers.Files.Folder 
						(
						this,
						null,
						i_FileDescriptor
						);

					InternalOnFolderAddedEvent(Folder);
				}
			}
			else
			{
				//  If one or more subscribers, broadcast event
				if (InternalOnFileAddedEvent != null)
				{
					GrooveWebServicesV12Helpers.Files.File File = new GrooveWebServicesV12Helpers.Files.File
						(
						this,
						null,
						i_FileDescriptor
						);

					InternalOnFileAddedEvent(File);
				}
			}
		}


		internal void RaiseFileDescriptorRenamedEvent(GrooveFilesWebService.FileDescriptor i_FileDescriptor)
		{
			if (i_FileDescriptor.Type == "Folder")
			{
				//  If one or more subscribers, broadcast event
				if (InternalOnFolderRenamedEvent != null)
				{
					GrooveWebServicesV12Helpers.Files.Folder Folder = new GrooveWebServicesV12Helpers.Files.Folder 
						(
						this,
						null,
						i_FileDescriptor
						);

					InternalOnFolderRenamedEvent(Folder);
				}
			}
			else
			{
				//  If one or more subscribers, broadcast event
				if (InternalOnFileRenamedEvent != null)
				{
					GrooveWebServicesV12Helpers.Files.File File = new GrooveWebServicesV12Helpers.Files.File
						(
						this,
						null,
						i_FileDescriptor
						);

					InternalOnFileRenamedEvent(File);
				}
			}
		}

		internal void RaiseFileDescriptorMovedEvent(GrooveFilesWebService.FileDescriptor i_FileDescriptor)
		{
			if (i_FileDescriptor.Type == "Folder")
			{
				//  If one or more subscribers, broadcast event
				if (InternalOnFolderMovedEvent != null)
				{
					GrooveWebServicesV12Helpers.Files.Folder Folder = new GrooveWebServicesV12Helpers.Files.Folder 
						(
						this,
						null,
						i_FileDescriptor
						);

					InternalOnFolderMovedEvent(Folder);
				}
			}
			else
			{
				//  If one or more subscribers, broadcast event
				if (InternalOnFileMovedEvent != null)
				{
					GrooveWebServicesV12Helpers.Files.File File = new GrooveWebServicesV12Helpers.Files.File
						(
						this,
						null,
						i_FileDescriptor
						);

					InternalOnFileMovedEvent(File);
				}
			}
		}

		internal void RaiseFileDescriptorRemovedEvent(string i_ID)
		{
			//  If one or more subscribers, broadcast event
			if (InternalOnRemovedEvent != null)
				InternalOnRemovedEvent(i_ID);
		}

		internal void RaiseFileDescriptorUpdatedEvent(GrooveFilesWebService.FileDescriptor i_FileDescriptor)
		{
			if (i_FileDescriptor.Type == "Folder")
			{
				//  If one or more subscribers, broadcast event
				if (InternalOnFolderUpdatedEvent != null)
				{
					GrooveWebServicesV12Helpers.Files.Folder Folder = new GrooveWebServicesV12Helpers.Files.Folder 
						(
						this,
						null,
						i_FileDescriptor
						);

					InternalOnFolderUpdatedEvent(Folder);
				}
			}
			else
			{
				//  If one or more subscribers, broadcast event
				if (InternalOnFileUpdatedEvent != null)
				{
					GrooveWebServicesV12Helpers.Files.File File = new GrooveWebServicesV12Helpers.Files.File
						(
						this,
						null,
						i_FileDescriptor
						);

					InternalOnFileUpdatedEvent(File);
				}
			}
		}

		internal void RaiseDownloadProgressedEvent(double i_BytesReceived, double i_BytesRemaining, string i_FileID)
		{
			//  If one or more subscribers, broadcast event
			if (InternalOnDownloadProgressedEvent != null)
			{
				InternalOnDownloadProgressedEvent
					(
					i_BytesReceived,
					i_BytesRemaining,
					i_FileID
					);
			}
		}

		public delegate void OnFileAddedDelegate(GrooveWebServicesV12Helpers.Files.File i_File);
		internal event OnFileAddedDelegate InternalOnFileAddedEvent;
		public event OnFileAddedDelegate OnFileAddedEvent
		{
			add
			{
				IncrementFilesToolSubscriptionCount();
				InternalOnFileAddedEvent += value;
			}
			remove
			{
				InternalOnFileAddedEvent -= value;

				DecrementFilesToolSubscriptionCount();
			}
		}

		public delegate void OnFileRenamedDelegate(GrooveWebServicesV12Helpers.Files.File i_File);
		internal event OnFileRenamedDelegate InternalOnFileRenamedEvent;
		public event OnFileRenamedDelegate OnFileRenamedEvent
		{
			add
			{
				IncrementFilesToolSubscriptionCount();
				InternalOnFileRenamedEvent += value;
			}
			remove
			{
				InternalOnFileRenamedEvent -= value;
				DecrementFilesToolSubscriptionCount();
			}
		}

		public delegate void OnFileMovedDelegate(GrooveWebServicesV12Helpers.Files.File i_File);
		internal event OnFileMovedDelegate InternalOnFileMovedEvent;
		public event OnFileMovedDelegate OnFileMovedEvent
		{
			add
			{
				IncrementFilesToolSubscriptionCount();
				InternalOnFileMovedEvent += value;
			}
			remove
			{
				InternalOnFileMovedEvent -= value;
				DecrementFilesToolSubscriptionCount();
			}
		}

		public delegate void OnFileUpdatedDelegate(GrooveWebServicesV12Helpers.Files.File i_File);
		internal event OnFileUpdatedDelegate InternalOnFileUpdatedEvent;
		public event OnFileUpdatedDelegate OnFileUpdatedEvent
		{
			add
			{
				IncrementFilesToolSubscriptionCount();
				InternalOnFileUpdatedEvent += value;
			}
			remove
			{
				InternalOnFileUpdatedEvent -= value;
				DecrementFilesToolSubscriptionCount();
			}
		}

		public delegate void OnFolderAddedDelegate(GrooveWebServicesV12Helpers.Files.Folder i_Folder);
		internal event OnFolderAddedDelegate InternalOnFolderAddedEvent;
		public event OnFolderAddedDelegate OnFolderAddedEvent
		{
			add
			{
				IncrementFilesToolSubscriptionCount();
				InternalOnFolderAddedEvent += value;
			}
			remove
			{
				InternalOnFolderAddedEvent -= value;

				DecrementFilesToolSubscriptionCount();
			}
		}

		public delegate void OnFolderRenamedDelegate(GrooveWebServicesV12Helpers.Files.Folder i_Folder);
		internal event OnFolderRenamedDelegate InternalOnFolderRenamedEvent;
		public event OnFolderRenamedDelegate OnFolderRenamedEvent
		{
			add
			{
				IncrementFilesToolSubscriptionCount();
				InternalOnFolderRenamedEvent += value;
			}
			remove
			{
				InternalOnFolderRenamedEvent -= value;
				DecrementFilesToolSubscriptionCount();
			}
		}

		public delegate void OnFolderMovedDelegate(GrooveWebServicesV12Helpers.Files.Folder i_Folder);
		internal event OnFolderMovedDelegate InternalOnFolderMovedEvent;
		public event OnFolderMovedDelegate OnFolderMovedEvent
		{
			add
			{
				IncrementFilesToolSubscriptionCount();
				InternalOnFolderMovedEvent += value;
			}
			remove
			{
				InternalOnFolderMovedEvent -= value;
				DecrementFilesToolSubscriptionCount();
			}
		}

		public delegate void OnFolderUpdatedDelegate(GrooveWebServicesV12Helpers.Files.Folder i_Folder);
		internal event OnFolderUpdatedDelegate InternalOnFolderUpdatedEvent;
		public event OnFolderUpdatedDelegate OnFolderUpdatedEvent
		{
			add
			{
				IncrementFilesToolSubscriptionCount();
				InternalOnFolderUpdatedEvent += value;
			}
			remove
			{
				InternalOnFolderUpdatedEvent -= value;
				DecrementFilesToolSubscriptionCount();
			}
		}

		public delegate void OnRemovedDelegate(string i_FileURI);
		internal event OnRemovedDelegate InternalOnRemovedEvent;
		public event OnRemovedDelegate OnRemovedEvent
		{
			add
			{
				IncrementFilesToolSubscriptionCount();
				InternalOnRemovedEvent += value;
			}
			remove
			{
				InternalOnRemovedEvent -= value;
				DecrementFilesToolSubscriptionCount();
			}
		}

		public delegate void OnDownloadProgressedDelegate(double i_BytesReceived, double i_BytesRemaining, string i_FileID);
		internal event OnDownloadProgressedDelegate InternalOnDownloadProgressedEvent;
		public event OnDownloadProgressedDelegate OnDownloadProgressedEvent
		{
			add
			{
				IncrementFilesToolSubscriptionCount();
				InternalOnDownloadProgressedEvent += value;
			}
			remove
			{
				InternalOnDownloadProgressedEvent -= value;
				DecrementFilesToolSubscriptionCount();
			}
		}

		#endregion

		#region GrooveWebServicesV12HelpersBase Implementation

		public override object BindToObject(ref string[] i_URLParts, int i_URLPartIndex)
		{
			object BindResult = null;

			string FileDescriptorURI = this.Data + "/" + i_URLParts[i_URLPartIndex];

			try
			{
				//  ---------------------------------------------------------------------------------------
				//  HACK ALERT:  Since there is no ReadEntry method, must read all entries and do uri match

					GrooveFilesWebService.FileDescriptor[] FileDescriptors = this.int_GetFileDescriptors
						(
						this.Data,
						true
						);

					foreach (GrooveFilesWebService.FileDescriptor FileDescriptor in FileDescriptors)
					{
						if (FileDescriptor.URI == FileDescriptorURI)
						{
							if (FileDescriptor.Type == "File")
							{
								BindResult = new GrooveWebServicesV12Helpers.Files.File
									(
									this,
									null,
									FileDescriptor
									);

								break;
							}
							else if (FileDescriptor.Type == "Folder")
							{
								BindResult = new GrooveWebServicesV12Helpers.Files.Folder 
									(
									this,
									null,
									FileDescriptor
									);

								break;
							}
							else
								throw new System.Exception("Unknown file descriptor type: " + FileDescriptor.Type);
						}
					}

				//  ---------------------------------------------------------------------------------------

				if (BindResult == null)
					throw new System.Exception("Unable to find file descriptor '" + FileDescriptorURI +"'");
			}
			catch (System.Exception Exception)
			{
				throw new System.Exception("Unable to find file descriptor '" + FileDescriptorURI + "' (" + Exception.Message + ")");
			}

			return BindResult;
		}

		#endregion
	
		#region IGrooveWebServicesEventCallback Members

		public void ProcessEvent(GrooveEventsWebService.Event i_Event)
		{
			switch (i_Event.EventType)
			{
				case GrooveWebServicesV12Helpers.Shared.GROOVE_FILE_ADD_EVENT_TYPE:
				{
					GrooveEventsWebService.GrooveFileAddEventData FileAddEventData = (GrooveEventsWebService.GrooveFileAddEventData)i_Event.EventData;
					this.RaiseFileDescriptorAddedEvent(FileAddEventData.FileDescriptor);

					break;
				}

				case GrooveWebServicesV12Helpers.Shared.GROOVE_FILE_DELETE_EVENT_TYPE:
				{
					GrooveEventsWebService.GrooveFileDeleteEventData FileDeleteEventData = (GrooveEventsWebService.GrooveFileDeleteEventData)i_Event.EventData;
					this.RaiseFileDescriptorRemovedEvent(FileDeleteEventData.FileID);

					break;
				}

				case GrooveWebServicesV12Helpers.Shared.GROOVE_FILE_RENAME_EVENT_TYPE:
				{
					GrooveEventsWebService.GrooveFileRenameEventData FileRenameEventData = (GrooveEventsWebService.GrooveFileRenameEventData)i_Event.EventData;
					this.RaiseFileDescriptorRenamedEvent(FileRenameEventData.FileDescriptor);

					break;
				}

				case GrooveWebServicesV12Helpers.Shared.GROOVE_FILE_DOWNLOAD_PROGRESS_EVENT_TYPE:
				{
					GrooveEventsWebService.GrooveFileDownloadProgressEventData FileDownloadProgressEventData = (GrooveEventsWebService.GrooveFileDownloadProgressEventData)i_Event.EventData;
					this.RaiseDownloadProgressedEvent
						(
						FileDownloadProgressEventData.BytesReceived,
						FileDownloadProgressEventData.BytesRemaining,
						FileDownloadProgressEventData.FileID
						);
					
					break;
				}

				case GrooveWebServicesV12Helpers.Shared.GROOVE_FILE_MOVE_EVENT_TYPE:
				{
					GrooveEventsWebService.GrooveFileMoveEventData FileMoveEventData = (GrooveEventsWebService.GrooveFileMoveEventData)i_Event.EventData;
					this.RaiseFileDescriptorMovedEvent(FileMoveEventData.FileDescriptor);
					
					break;
				}

				case GrooveWebServicesV12Helpers.Shared.GROOVE_FILE_UPDATE_EVENT_TYPE:
				{
					GrooveEventsWebService.GrooveFileUpdateEventData FileUpdateEventData = (GrooveEventsWebService.GrooveFileUpdateEventData)i_Event.EventData;
					this.RaiseFileDescriptorUpdatedEvent(FileUpdateEventData.FileDescriptor);

					break;
				}

				default:
				{
					System.Diagnostics.Debug.WriteLine("[FilesTool]Unknown event type: " + i_Event.EventType);
					break;
				}
			}

		}

		#endregion
	}
}
